/**
 * 应用历史记录管理工具
 * 使用 @lazycatcloud/minidb 保存应用历史并自动恢复
 */

import { MiniDB } from '@lazycatcloud/minidb'

export interface AppInfo {
  appid: string
  title?: string
  description?: string
  icon?: string
  domain: string
  status?: number
  instanceStatus?: number
  [key: string]: any
}

const MAX_HISTORY_COUNT = 20

// 初始化 MiniDB 实例
const db = new MiniDB()
const collection = db.getCollection('appHistory')

/**
 * 从 minidb 读取应用历史
 */
export async function loadAppHistory(): Promise<AppInfo[]> {
  try {
    // 使用 $exists 查询所有有 openedAt 字段的记录，按时间倒序排列
    const history = await collection.find({ $exists: 'openedAt' }, { sort: ['-openedAt'], limit: MAX_HISTORY_COUNT * 2 }).fetch() as AppInfo[]
    
    // 去重：确保同一个应用只出现一次（优先使用 appid，如果没有则使用 domain）
    // 保留 openedAt 最新的记录
    const uniqueHistoryMap = new Map<string, AppInfo>()
    for (const app of history) {
      // 优先使用 appid 作为唯一标识，如果没有则使用 domain
      const key = app.appid || app.domain
      if (key) {
        const existing = uniqueHistoryMap.get(key)
        if (!existing || (app.openedAt && existing.openedAt && app.openedAt > existing.openedAt)) {
          uniqueHistoryMap.set(key, app)
        }
      }
    }
    
    // 转换为数组并按 openedAt 排序
    const uniqueHistory = Array.from(uniqueHistoryMap.values())
      .sort((a, b) => (b.openedAt || 0) - (a.openedAt || 0))
      .slice(0, MAX_HISTORY_COUNT)
    
    return uniqueHistory
  } catch (error) {
    console.error('读取应用历史失败:', error)
    return []
  }
}

/**
 * 保存应用历史到 minidb
 */
export async function saveAppHistory(history: AppInfo[]): Promise<void> {
  try {
    // 限制历史记录数量
    const limitedHistory = history.slice(0, MAX_HISTORY_COUNT)
    
    // 去重：确保同一个应用只出现一次（优先使用 appid，如果没有则使用 domain）
    // 保留第一个出现的
    const uniqueHistory: AppInfo[] = []
    const seenKeys = new Set<string>()
    for (const app of limitedHistory) {
      // 优先使用 appid 作为唯一标识，如果没有则使用 domain
      const key = app.appid || app.domain
      if (key && !seenKeys.has(key)) {
        seenKeys.add(key)
        uniqueHistory.push(app)
      }
    }
    
    // 为每个应用添加 openedAt 时间戳（如果还没有）
    const historyWithTimestamp = uniqueHistory.map((app, index) => ({
      ...app,
      openedAt: app.openedAt || new Date().getTime() - index // 保持原有顺序
    }))
    
    // 清理数据，只保留必要的字段（appid、icon、domain、openedAt），并准备批量 upsert
    // 优先使用 appid 作为唯一标识，如果没有 appid 则使用 domain
    // 不保存 status 等会变化的字段
    const docsToUpsert = historyWithTimestamp.map(app => ({
      id: app.appid || app.domain, // 优先使用 appid，如果没有则使用 domain
      appid: app.appid,
      icon: app.icon,
      domain: app.domain,
      openedAt: app.openedAt
    }))
    
    // 批量 upsert（根据 RemoteDB 源码，直接传入文档数组）
    // upsert 会根据 id 字段来判断是更新还是插入
    if (docsToUpsert.length > 0) {
      await collection.upsert(docsToUpsert)
      
      // 清理重复记录和超出限制的旧记录
      try {
        // 获取所有记录
        const allRecords = await collection.find({ $exists: 'openedAt' }, { sort: ['-openedAt'] }).fetch()
        
        // 按 appid 分组，保留每个 appid 最新的记录
        const recordsByAppid = new Map<string, any>()
        for (const record of allRecords) {
          const appid = (record as any).appid
          if (appid) {
            const existing = recordsByAppid.get(appid)
            const recordOpenedAt = (record as any).openedAt || 0
            const existingOpenedAt = existing ? ((existing as any).openedAt || 0) : 0
            if (!existing || recordOpenedAt > existingOpenedAt) {
              recordsByAppid.set(appid, record)
            }
          }
        }
        
        // 找出需要删除的记录（重复的或超出限制的）
        const recordsToKeep = Array.from(recordsByAppid.values())
          .sort((a, b) => ((b as any).openedAt || 0) - ((a as any).openedAt || 0))
          .slice(0, MAX_HISTORY_COUNT)
        
        const idsToKeep = new Set<string>()
        for (const record of recordsToKeep) {
          const id = (record as any)._id || (record as any).id || (record as any).appid
          if (id) {
            idsToKeep.add(String(id))
          }
        }
        
        // 收集所有需要删除的记录 id
        const idsToDelete: string[] = []
        for (const record of allRecords) {
          const id = (record as any)._id || (record as any).id || (record as any).appid
          if (id && !idsToKeep.has(String(id))) {
            idsToDelete.push(String(id))
          }
        }
        
        // 批量删除重复记录和超出限制的记录
        if (idsToDelete.length > 0) {
          await collection.remove(idsToDelete)
        }
      } catch (error) {
        console.warn('清理重复和旧记录时出错:', error)
      }
    }
    
  } catch (error) {
    console.error('保存应用历史失败:', error)
  }
}

/**
 * 添加应用到历史记录
 * @param app 要添加的应用
 * @param currentHistory 当前历史记录数组（已废弃，不再使用，保留以保持接口兼容）
 * @returns 更新后的历史记录数组
 */
export async function addToHistory(app: AppInfo, _currentHistory?: AppInfo[]): Promise<AppInfo[]> {
  // 直接从数据库加载最新的历史记录
  const dbHistory = await loadAppHistory()
  
  // 检查应用是否已经在历史记录中（使用 appid 或 domain 来匹配）
  // 注意：数据库返回的记录可能包含 id 字段，但我们需要用 appid 来匹配
  const existingIndex = dbHistory.findIndex(h => {
    // 优先使用 appid 匹配，如果没有 appid 则使用 domain
    return (h.appid && app.appid && h.appid === app.appid) || 
           (h.domain && app.domain && h.domain === app.domain)
  })
  
  // 如果已存在，更新其 openedAt 时间戳并移到最前面
  // 如果不存在，添加到最前面
  const appWithTimestamp = {
    ...app,
    openedAt: new Date().getTime()
  }
  
  let updatedHistory: AppInfo[]
  if (existingIndex !== -1) {
    // 已存在，移除旧记录，添加新记录到最前面
    updatedHistory = [...dbHistory]
    updatedHistory.splice(existingIndex, 1)
    updatedHistory.unshift(appWithTimestamp)
  } else {
    // 不存在，直接添加到最前面
    updatedHistory = [appWithTimestamp, ...dbHistory]
  }
  
  // 限制历史记录数量
  const limitedHistory = updatedHistory.slice(0, MAX_HISTORY_COUNT)
  
  // 保存到 minidb
  // 注意：saveAppHistory 会使用 id: app.appid 来确保 upsert 能正确识别和更新记录
  await saveAppHistory(limitedHistory)
  
  return limitedHistory
}

/**
 * 获取最近打开的应用
 * @returns 最近打开的应用，如果没有则返回 null
 */
export async function getLastOpenedApp(): Promise<AppInfo | null> {
  try {
    const history = await collection.find({ $exists: 'openedAt' }, { sort: ['-openedAt'], limit: 1 }).fetch()
    return history.length > 0 ? (history[0] as AppInfo) : null
  } catch (error) {
    console.error('获取最近打开的应用失败:', error)
    return null
  }
}

/**
 * 清除所有历史记录
 */
export async function clearAppHistory(): Promise<void> {
  try {
    // 获取所有记录
    const allRecords = await collection.find({ $exists: 'openedAt' }).fetch()
    // 提取所有记录的 id（RemoteDB 的 remove 需要 id 数组）
    const idsToDelete: string[] = []
    for (const record of allRecords) {
      // 尝试获取记录的 id（可能是 _id, id, 或 appid）
      const id = (record as any)._id || (record as any).id || (record as any).appid
      if (id) {
        idsToDelete.push(String(id))
      }
    }
    // 批量删除（RemoteDB 的 remove 接受 id 数组）
    if (idsToDelete.length > 0) {
      await collection.remove(idsToDelete)
    }
  } catch (error) {
    console.error('清除应用历史失败:', error)
  }
}

